#ifndef COMMON_BASEMESHUTIL_H
#define COMMON_BASEMESHUTIL_H

#include "BaseMesh.h"

template <typename IndexArrayType>
TriArray to_triangles(const IndexArrayType& I)
{
    size_t   triCount = I.size() / 3;
    TriArray T;
    T.reserve(triCount);
    for (int i = 0; i < I.size(); i += 3)
        T.emplace_back(I[i], I[i + 1], I[i + 2]);
    return T;
}

template <typename IndexArrayType>
IndexArrayType to_indices(const TriArray& T)
{
    size_t         indexCount = T.size() * 3;
    IndexArrayType I;
    I.reserve(indexCount);
    for (const auto& t : T)
    {
        I.emplace_back(t.x);
        I.emplace_back(t.y);
        I.emplace_back(t.z);
    }
    return I;
}

template <typename Vec3ArrayType, typename IndexArrayType>
bool make_face_normal(const Vec3ArrayType&  X,
                      const IndexArrayType& I,
                      Vec3ArrayType&        FN)
{
    FN.resize(I.size() / 3);
    for (int i = 0; i < I.size(); i += 3)
    {
        const auto& v1 = X[I[i]];
        const auto& v2 = X[I[i + 1]];
        const auto& v3 = X[I[i + 2]];
        FN[i / 3]      = norm((v2 - v1) ^ (v3 - v1));
    }
    return true;
}

template <typename Vec3ArrayType, typename IndexArrayType>
bool make_vertex_normal(const Vec3ArrayType&  X,
                        const IndexArrayType& I,
                        const Vec3ArrayType&  FN,
                        Vec3ArrayType&        VN)
{
    VN.resize(X.size());
    for (auto& n : VN)
    {
        n[0] = 0;
        n[1] = 0;
        n[2] = 0;
    }

    for (int i = 0; i < I.size(); i += 3)
    {
        auto n = FN[i / 3];
        VN[I[i]] += n;
        VN[I[i + 1]] += n;
        VN[I[i + 2]] += n;
    }
    for (auto& vn : VN)
        normalize(vn);

    return true;
}
#endif //COMMON_BASEMESHUTIL_H
